using System;
using System.Threading;

namespace Catastrophe.Common.ThreadLock
{
	internal sealed class AdvancedHybirdLock : IDisposable
	{
		private bool disposedValue = false;

		private int m_waiters = 0;

		private AutoResetEvent m_waiterLock = new AutoResetEvent(initialState: false);

		private int m_spincount = 4000;

		private int m_owningThreadId = 0;

		private int m_recursion = 0;

		private void Dispose(bool disposing)
		{
			if (!this.disposedValue)
			{
				if (disposing)
				{
				}
				this.m_waiterLock.Close();
				this.disposedValue = true;
			}
		}

		public void Dispose()
		{
			this.Dispose(disposing: true);
		}

		public void Enter()
		{
			int managedThreadId = Thread.CurrentThread.ManagedThreadId;
			if (managedThreadId == this.m_owningThreadId)
			{
				this.m_recursion++;
			}
			else if (Interlocked.Increment(ref this.m_waiters) != 1)
			{
				this.m_waiterLock.WaitOne();
			}
		}

		public void Leave()
		{
			if (Interlocked.Decrement(ref this.m_waiters) != 0)
			{
				this.m_waiterLock.Set();
			}
		}
	}
}
